// NMI's Java Code Viewer 6.0a
// www.trinnion.com/javacodeviewer

// Registered to Evaluation Copy                                      
// Generated PGFZKD AyTB 14 2007 15:43:34 

//source File Name:   DMI.java

package com.chiyou.common.indicator;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.chiyou.common.models.HisData;

public class DMI extends IndicatorBase {

	private final int m_iParam[] = { 11 , 6, 5 };

	private List<HisData> m_kDatas;

	public List<HisData> getM_kDatas() {
		return m_kDatas;
	}

	public void setM_kDatas(List<HisData> m_kDatas) {
		this.m_kDatas = m_kDatas;
	}

	public DMI() {
		// super(pos, Precision);
		super.m_strIndicatorName = "DMI";
		super.m_strIndicatorName += "(";
		for (int i = 0; i < m_iParam.length; i++) {
			if (i > 0)
				super.m_strIndicatorName += ",";
			super.m_strIndicatorName += m_iParam[i];
		}

		super.m_strIndicatorName += ")";
		super.m_strParamName = (new String[] { "+DI", "-DI", "ADX", "ADXR" });
		super.m_iPrecision = 2;
	}

	public DMI(IndicatorPos pos, int Precision) {
		super(pos, Precision);
		super.m_strIndicatorName = "DMI";
		super.m_strIndicatorName += "(";
		for (int i = 0; i < m_iParam.length; i++) {
			if (i > 0)
				super.m_strIndicatorName += ",";
			super.m_strIndicatorName += m_iParam[i];
		}

		super.m_strIndicatorName += ")";
		super.m_strParamName = (new String[] { "+DI", "-DI", "ADX", "ADXR" });
		super.m_iPrecision = 2;
	}

	
	/**
	 * TR = SUM(MAX(MAX(HIGH - LOW, ABS(HIGH-REF(CLOSE,1))), ABS(LOW - REF(CLOSE, 1))), N)

HD = HIGH - REF(HIGH, 1)

LD = REF(LOW, 1) - LOW

DMP = SUM(IF(HD>0 AND HD>LD, HD, 0), N)

DMM = SUM(IF(LD>0 AND LD>HD, LD, 0), N)

PDI = DMP*100/TR

MDI = DMM*100/TR

DX = ABS(MDI - PDI)/(MDI + PDI)*100

ADX = MA(ABS(MDI - PDI)/(MDI + PDI)*100, M)
	 */
	
	
	
	
	public void Calculate() {
		String code = getM_kDatas().get(0).getCODE();
		int n1 = m_iParam[0];
		int n2 = m_iParam[1];
		int n3 = m_iParam[2];

		float DMP[] = new float[this.m_kDatas.size()];
		float DMM[] = new float[this.m_kDatas.size()];
		float PDI[] = new float[this.m_kDatas.size()];
		float MDI[] = new float[this.m_kDatas.size()];
		float DX1[] = new float[this.m_kDatas.size()];
		float ADX1[] = new float[this.m_kDatas.size()];
		
		float zDI[] = new float[this.m_kDatas.size()];
		float fDI[] = new float[this.m_kDatas.size()];
		float TR[] = new float[this.m_kDatas.size()];
		float ADX[] = new float[this.m_kDatas.size()];
		float ADXR[] = new float[this.m_kDatas.size()];
		float zDM[] = new float[this.m_kDatas.size()];
		float fDM[] = new float[this.m_kDatas.size()];
		float DX[] = new float[this.m_kDatas.size()];

		float a;
		float b;
		float c;
		float max = 0.0f;
		// for (int i = 1; i < m_kDatas.size(); i++) {
		// a = Math.abs(m_kDatas.get(i).getHIGH() - m_kDatas.get(i).getLOW());
		// b = Math.abs(m_kDatas.get(i).getHIGH() - m_kDatas.get(i -
		// 1).getCLOSE());
		// c = Math.abs(m_kDatas.get(i).getLOW() - m_kDatas.get(i -
		// 1).getCLOSE());
		// TR[i] = Math.max(a, Math.max(b, c));
		// a = m_kDatas.get(i).getHIGH() - m_kDatas.get(i - 1).getHIGH();
		// b = m_kDatas.get(i - 1).getLOW() - m_kDatas.get(i).getLOW();
		// a = a > 0.0 ? a : 0.0f;
		// b = b > 0.0f ? b : 0.0f;
		//
		// zDM[i] = 0.0F;
		// fDM[i] = 0.0F;
		// if (a > b)
		// zDM[i] = a;
		// else if (a < b)
		// fDM[i] = b;
		// }

		
		
		
		for (int i = n1; i < m_kDatas.size(); i++) {
			float _zdm = 0.0F;
			float _fdm = 0.0F;
			float _wdm = 0.0F;
			

			_zdm = m_kDatas.get(i).getHIGH() - m_kDatas.get(i - 1).getLOW();

			if (_zdm <= Math.abs(m_kDatas.get(i).getLOW() - m_kDatas.get(i - 1).getLOW())) {
				_zdm = 0;
			}

			_fdm = m_kDatas.get(i).getLOW() - m_kDatas.get(i-1 ).getLOW();

			if (_fdm <= Math.abs(m_kDatas.get(i).getHIGH() - m_kDatas.get(i - 1).getLOW())) {
				_fdm = 0;
			}

//			if (_zdm == 0 && _fdm == 0) {
//				_wdm = 0;
//				_fdm = _zdm = 0;
//			}
//			
//			if (m_kDatas.get(i).getHIGH() < m_kDatas.get(i - 1).getHIGH() && m_kDatas.get(i).getLOW() > m_kDatas.get(i - 1).getLOW()) {
//				_wdm = 0;
//				_fdm = _zdm = 0;
//			}

			a = m_kDatas.get(i).getHIGH() - m_kDatas.get(i).getLOW();
			b = m_kDatas.get(i).getHIGH() - m_kDatas.get(i - 1).getCLOSE();
			c = m_kDatas.get(i).getLOW() - m_kDatas.get(i - 1).getCLOSE();
			TR[i] = Math.abs(Math.max(a, Math.max(b, c)));
			
			a = m_kDatas.get(i).getHIGH() - m_kDatas.get(i - 1).getHIGH();
			b = m_kDatas.get(i - 1).getLOW() - m_kDatas.get(i).getLOW();
			a = a > 0.0 ? a : 0.0f;
			b = b > 0.0f ? b : 0.0f;

			zDM[i] = 0F;
			fDM[i] = 0F;
			
			if (a > b)
				zDM[i] = a;
			else if (a < b)
				fDM[i] = b;
//			zDM[i] = _zdm >0.0 ? _zdm : 0.0f;
//			fDM[i] = _fdm>0.0 ? _fdm : 0.0f;
//			System.out.println("_zdm .......... "+ _zdm +" "+_fdm);
//			System.out.println("zDM .......... "+ zDM[i] +" "+fDM[i]);
		}

		a = b = c = 0.0F;
		for (int i = 0; i < n1; i++) {
			a += TR[i];
			b += zDM[i];
			c += fDM[i];
		}

		float prefDI;
		float prezDI = prefDI = 0.0F;
		for (int i = n1; i < m_kDatas.size(); i++) {
			a += TR[i];
			b += zDM[i];
			c += fDM[i];
			zDI[i] = prezDI;
			fDI[i] = prefDI;
			if (a != 0.0F) {
				zDI[i] = ((b / n1) / (a / n1)) * 100F;
				fDI[i] = ((c / n1) / (a / n1)) * 100F;
			}
			prezDI = zDI[i];
			prefDI = fDI[i];
			int j = (i - n1) + 1;
			a -= TR[j];
			b -= zDM[j];
			c -= fDM[j];
		}

		for (int i = n1; i < m_kDatas.size(); i++) {
			if (zDI[i] + fDI[i] != 0.0F)
				DX[i] = (Math.abs(zDI[i] - fDI[i]) / Math.abs(zDI[i] + fDI[i])) * 100F;
			else
				DX[i] = 0.0F;
		}

		IndicatorBase.Average(n1, m_kDatas.size(), n2, DX, ADX);
		for (int i = (n1 + n2 + n3) - 1; i < m_kDatas.size(); i++) {
			ADXR[i] = (ADX[i] + ADX[i - n3]) / 2.0F;
		}
		// for (int i = n1+ n2 ; i < m_kDatas.size(); i++) {
		// ADXR[i] = (ADX[i] + ADX[i - 1]) / 2.0F;
		// }
		DecimalFormat decimalFormat = new DecimalFormat(".00");

		for (int i = 0; i < m_kDatas.size(); i++) {
			Map map = new HashMap();
			map.put("adx", Float.valueOf(decimalFormat.format(ADX[i])));
			map.put("zdi", Float.valueOf(decimalFormat.format(zDI[i])));
			map.put("fdi", Float.valueOf(decimalFormat.format(fDI[i])));
			map.put("zdm", Float.valueOf(decimalFormat.format(zDM[i])));
			map.put("fdm", Float.valueOf(decimalFormat.format(fDM[i])));
			map.put("tr", Float.valueOf(decimalFormat.format(TR[i])));
			map.put("adxr", Float.valueOf(decimalFormat.format(ADXR[i])));
			map.put("date", date2String(m_kDatas.get(i).getTIME(), "YYYY-MM-dd HH:mm:ss"));
			System.out.println("zdi : " +  Float.valueOf(decimalFormat.format(zDI[i])) + " fdi : " + fDI[i] +" "+date2String(m_kDatas.get(i).getTIME(), "YYYY-MM-dd HH:mm:ss"));
			addIndicators(map);
		}

	}

	private void Average2(int begin, int iCount, int n, float source[], float destination[]) {
		if (source == null || destination == null)
			return;
		if (n > iCount - begin || n < 1)
			return;
		float prevalue = 0.0F;
		double sum = 0.0D;
		for (int i = begin; i < iCount; i++)
			sum += source[i];

		for (int i = iCount - 1; i >= (begin + n) - 1; i--) {
			sum -= prevalue;
			sum += source[(i - n) + 1];
			prevalue = source[i];
			destination[i] = (float) (sum / (double) n);
		}

	}

	public static String long2String(long longTime, String dataFormat) {
		Date d = new Date(longTime);
		SimpleDateFormat s = new SimpleDateFormat(dataFormat);
		String str = s.format(d);
		return str;
	}

	public int isBuyOrSell() {
		// TODO Auto-generated method stub
		List dimList = this.getIndicators();
		int lastStatus = 0;
		int s = 0;
		for (int i = 1; i < dimList.size(); i++) {
			Map dmiMap = (Map) dimList.get(i);
			float zdi = Float.parseFloat("" + dmiMap.get("zdi"));
			float fdi = Float.parseFloat("" + dmiMap.get("fdi"));
			int status = 0;
			if (zdi > fdi) {
				status = 1;
			}

			if (fdi > zdi) {
				status = -1;
			}

			if (status == 1) {
				// System.out.println("buy...");
				s = 10;
				if (lastStatus == -1) {
					System.out.println("dmi买单" + dmiMap.get("date"));
					s = 1;
				}
			}

			if (status == -1) {
				// System.out.println("sell...");
				s = -10;

				if (lastStatus == 1) {
					System.out.println("dmi卖单" + dmiMap.get("date"));
					s = -1;
				}
			}
			
			lastStatus = status;
		}

		return s;
	}

	private int getNextIndex(int i, int size) {
		return i + 1 < size ? i + 1 : i;
	}

	public static String date2String(Date time, String dataFormat) {
		SimpleDateFormat s = new SimpleDateFormat(dataFormat);
		String str = s.format(time);
		return str;
	}

	public boolean isSellTime() {
		// TODO Auto-generated method stub
		List dimList = this.getIndicators();
		int isDown = 0;
		for (int i = 1; i < dimList.size() - 1; i++) {
			Map dmiMap = (Map) dimList.get(i);
			Map lastdmiMap = (Map) dimList.get(i - 1);
			Map nextdmiMap = (Map) dimList.get(getNextIndex(i, dimList.size()));
			float zdi = Float.parseFloat("" + dmiMap.get("zdi"));
			float fdi = Float.parseFloat("" + dmiMap.get("fdi"));

			float lzdi = Float.parseFloat("" + lastdmiMap.get("zdi"));
			float lfdi = Float.parseFloat("" + lastdmiMap.get("fdi"));

			float nzdi = Float.parseFloat("" + nextdmiMap.get("zdi"));
			float nfdi = Float.parseFloat("" + nextdmiMap.get("fdi"));

			if ((lzdi > lfdi && zdi < fdi && isDown <= 0) || (zdi > fdi && nzdi < nfdi && isDown <= 0)) {
				isDown = 1;
			} else {
				isDown = 0;
			}
		}
		if (isDown > 0)
			return true;
		return false;
	}

}
